package com.lj.mcore.dao.base;

import jakarta.persistence.*;

import java.io.Serializable;
import java.lang.reflect.ParameterizedType;
import java.util.*;

public class BaseAppDAOimpl<T> implements BaseAppDAO<T> {

    protected  Class<T> entityClass;

    protected  final String className;

    @PersistenceContext
    private EntityManager entityManager;

    public BaseAppDAOimpl(){

        ParameterizedType t = (ParameterizedType) this.getClass().getGenericSuperclass();
        //获取泛型参数的实际类型
        this.entityClass = (Class<T>) t.getActualTypeArguments()[0];
        this.className = entityClass.getSimpleName();
    }
    
    @Override
    public boolean save(T entity){
        boolean flag=false;
        try {
            entityManager.persist(entity);
            flag=true;
        }catch (Exception e){
            e.printStackTrace();
        }

        return flag;
    }
    
    @Override
    public T findById(Serializable id) {
        return entityManager.find(entityClass,id);
    }


    public List<T> query( String hql, final Map params, final int begin, final int max)
    {
        Query query  = entityManager.createQuery(hql);
        if ((params != null) && (params.size() > 0)) {
            for (Iterator localIterator = params.keySet().iterator(); localIterator.hasNext(); ) { Object key = localIterator.next();
                query.setParameter(key.toString(), params.get(key));
            }
        }
        if ((begin >= 0) && (max > 0)) {
            query.setFirstResult(begin);
            query.setMaxResults(max);
        }
        List list =  query.getResultList();
        if ((list != null) && (list.size() > 0)) {
            return list;
        }

        return new ArrayList();
    }

    @Override
    public List querySql(String sql, Map params, int begin, int max) {

        Query query  = entityManager.createNativeQuery(sql);

        if ((params != null) && (params.size() > 0)) {
            for (Iterator localIterator = params.keySet().iterator(); localIterator.hasNext(); ) { Object key = localIterator.next();
                query.setParameter(key.toString(), params.get(key));
            }
        }
        if ((begin >= 0) && (max > 0)) {
            query.setFirstResult(begin);
            query.setMaxResults(max);
        }
        List list =  query.getResultList();
        if ((list != null) && (list.size() > 0)) {
            return list;
        }

        return new ArrayList();
    }

    @Override
    public T getSingleResult(Map params) {

        String hql = "from "+this.className+" obj";

        if (params!=null && params.size()>0){
            hql+=" where ";
            for (Iterator localIterator = params.keySet().iterator(); localIterator.hasNext(); ) {
                Object key = localIterator.next();
                hql+="obj."+key.toString() +" =:"+key.toString()+" and ";
            }
            hql = hql.substring(0,hql.length()-4);
        }

        Query query=entityManager.createQuery(hql);
        for (Iterator localIterator = params.keySet().iterator(); localIterator.hasNext(); ) {
            Object key = localIterator.next();
            query.setParameter(key.toString(), params.get(key));
        }
        Object o= null;
        try{
            o= query.getSingleResult();
        }catch (NoResultException e){
            return null;
        }finally {
            entityManager.close();
        }
        entityManager.close();
        return (T) o;
    }

    @Override
    public List<T> pageQuery(String hql, String filed, Object o, int start, int pageNumer) {
        return null;
    }
    
    @Override
    public boolean update(T entity) {
        boolean flag = false;
        try {
            entityManager.merge(entity);
            flag = true;
        } catch (Exception e) {
            System.out.println("---------------更新出错---------------");
        }
        return flag;
    }

    @Override
    public int executeUpdate(String sql, Map params) {
        Query query  = entityManager.createNativeQuery(sql);

        if ((params != null) && (params.size() > 0)) {
            for (Iterator localIterator = params.keySet().iterator(); localIterator.hasNext(); ) { Object key = localIterator.next();
                query.setParameter(key.toString(), params.get(key));
            }
        }
        return query.executeUpdate();
    }

    @Override
    public List executeNativeSql(String sql, Map map,Object[] params, int begin, int max) {

            Query query = entityManager.createNamedQuery(sql);
            int parameterIndex = 1;
            if ((params != null) && (params.length > 0)) {
                for (Object obj : params) {
                    query.setParameter(parameterIndex++, obj);
                }
            }
            if ((begin >= 0) && (max > 0)) {
                query.setFirstResult(begin);
                query.setMaxResults(max);
            }
            return query.getResultList();
    }


    @Override
    public boolean delete(T entity) {
        boolean flag=false;
        try {
            entityManager.remove(entityManager.merge(entity));
            flag=true;
        }catch (Exception e){
            e.printStackTrace();
        }
        return flag;
    }

    @Override
    public Object findCount(String sql, LinkedHashMap<String, Object> map) {
        Set<String> set=null;
        set=map.keySet();
        List<String> list=new ArrayList<>(set);
        List<Object> filedlist=new ArrayList<>();
        for (String filed:list){
            sql+="u."+filed+"=? and ";
            filedlist.add(filed);
        }
        sql=sql.substring(0,sql.length()-4);
        System.out.println(sql+"--------sql语句-------------");
        Query query=entityManager.createQuery(sql);
        for (int i=0;i<filedlist.size();i++){
            query.setParameter(i+1,map.get(filedlist.get(i)));
        }
        return query.getSingleResult();
    }
}
